package com.itbbs.user.service.impl;

import com.itbbs.encrypt.JWTHelper;
import com.itbbs.encrypt.MD5;
import com.itbbs.exception.CustomizeException;
import com.itbbs.model.userModel.User;
import com.itbbs.model.userModel.UserInfo;
import com.itbbs.redis.client.RedisFeignClient;
import com.itbbs.result.ResultCodeEnum;
import com.itbbs.user.mapper.UserMapper;
import com.itbbs.user.service.api.UserInfoService;
import com.itbbs.user.service.api.UserService;
import com.itbbs.uuid.UUIDUtil;
import com.itbbs.vo.user.UserLoginVo;
import com.itbbs.vo.user.UserRegisteredVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author ysk
 * @version 1.0.1
 * @Description 用户服务接口的实现类
 * @createTime 2021年06月04日 10:18:00
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserInfoService userInfoServicel;

    @Resource
    private UserMapper userMapper;

    @Resource
    // redis的远程调用接口
    private RedisFeignClient redisFeignClient;

    @Override
    public Map<String, Object> loginUser(UserLoginVo loginVo) {
        // 调用service层去查询用户
        User user = userMapper.getUserByAccAndPaw(loginVo);
        if (user == null)
            throw new CustomizeException(ResultCodeEnum.ACCOUNT_ERR);
        if (user.getStatus() != 0)
            throw new CustomizeException(ResultCodeEnum.user_seal);
        // 根据用户的id去查询用户的的详细信息,获取到用户的详细信息
        UserInfo userInfo = userInfoServicel.getUserInfoByUserId(user.getId());
        // 将用户的用户名和和用户id生成token使用map封装
        Map<String, String> mapToken = new HashMap<>();
        mapToken.put("UserId", user.getId());
        mapToken.put("userName", user.getUsername());
        String token = JWTHelper.getToken(mapToken);
        // 封装返回给前端的信息
        Map<String, Object> map = new HashMap<>();
        map.put("UserId", user.getId());
        map.put("head_portrait", userInfo.getHeadPortrait());
        map.put("nickName", userInfo.getNickName());
        map.put("token", token);
        return map;
    }

    @Override
    @Transactional
    public void registrationUser(UserRegisteredVo registeredVo) {
        // 先进行数据的校验，调用redis中的服务获取到验证码
        String verifyCode = redisFeignClient.get(registeredVo.getKeyCode());
        if (verifyCode == null || !verifyCode.equals(registeredVo.getVerification())) {
            throw new CustomizeException(ResultCodeEnum.CODE_ERROR);
        }
        /*
            这里需要引用一个解密机制，解密用户名，用户名和密码在前端时就进行了加密，发送过来的就是加密过后的数据
         */
        String encrypt = MD5.encrypt(registeredVo.getPassword());
        registeredVo.setPassword(encrypt);
        // 对用户的数据进行处理,将vo转为user类
        User user = new User();
        BeanUtils.copyProperties(registeredVo, user);
        // 对数据进行初始化处理,不用设置状态，数据库已经设置了默认
        user.setId(UUIDUtil.getUUID());
        user.setCreationTime(new Date());
        user.setUpdateTime(new Date());
        int i = userMapper.insertSelective(user);
        if (i != 1) {
            throw new CustomizeException(ResultCodeEnum.SERVICE_ERROR);
        }
        // 初始化用户基础信息
        boolean isFlag = userInfoServicel.initUserInfo(user.getId(), user.getUsername(), user.getCreationTime());
        if (!isFlag) {
            throw new CustomizeException(ResultCodeEnum.SERVICE_ERROR);
        }
    }

    @Override
    public void ifExistsUserbyAccount(String account) {
        int i = userMapper.getUserbyAcc(account);
        // 数据存在
        if (i == 1){
            throw new CustomizeException(ResultCodeEnum.ACCOUNT_EXIST);
        }
    }

    @Override
    public void sendEmail(String account, Integer type) {
        User user = userMapper.getUserEmailByAccType(account,type);
        if (user == null){
            throw new CustomizeException(ResultCodeEnum.ACCOUNT_NOEXIST);
        }
        String email = user.getEmail();
        // TODO 调用邮箱服务
    }

    @Override
    public void resetPassByEmail(String email, Integer password) {
        int i = userMapper.updateUserPassWordByEmail(email,password);
        if (i == 1){
            throw new CustomizeException(ResultCodeEnum.INTERNET_ERR);
        }
    }
}
